# -*- coding: utf-8 -*-
"""
   File Name：     api.py
   Description :  Instantiate FaceRecognition from faceRecognition.py. Give a clear API for user.
   Author :       KangJiaHui
   date：         2020/01/14
"""

import json
from modules.face_server.faceRecognition import FaceRecognition
from modules.utils.error import RegisterFaceNum, FaceArea
import time

face = FaceRecognition()
print("FaceRcognition created!")


def face_register(image, score_reg):
    """
    Registers only one face in one picture.
    :param score_reg: float, the score of the face to be registered should be larger than score_reg
    :param image: array image
    :return: json:
        e.x. {"feature_vector": list}
    """
    try:
        t1 = time.time()
        feature_vector = face.face_register(image, score_reg)
        print(time.time() - t1)
        result_json = json.dumps({"result": 0, "message": "SUCCESS", "feature_vector": feature_vector})
    except RegisterFaceNum as e:
        msg = str(e)
        result_json = json.dumps({"result": -2, "message": msg})
    except FaceArea as e:
        msg = str(e)
        result_json = json.dumps({"result": -3, "message": msg})
    except Exception as e:
        msg = str(e)
        result_json = json.dumps({"result": -1, "message": msg})
    return result_json


def match_identity(feature_vector, thresh, score_rec, image_base64=None, path=None):
    """
    Match the input feature vector and vector for each face in one image.
    Once a face matched, it will return True.
    If path and image coexist, then path will cover image.
    :param score_rec: float, the score of detected faces should be larger than score_rec
    :param feature_vector: list, the feature vector to be matched
    :param thresh: distance between face and matched face should be smaller than thresh
    :param image_base64: image encoded in base64
    :param path: str, indicates an image
    :return:json:
        e.x. {"result": 0, "message": "SUCCESS", "flag": True}
    """
    try:
        if path:
            flag, dist = face.match_identity(feature_vector, thresh, score_rec, path=path)
        else:
            flag, dist = face.match_identity(feature_vector, thresh, score_rec, image_base64=image_base64)
        result_json = json.dumps({"result": 0, "message": "SUCCESS", "flag": flag, "distance": dist})
    except Exception as e:
        msg = str(e)
        result_json = json.dumps({"result": -1, "message": msg})
    return result_json


def match_vectors(ref_id, feature_vector, candidate_dict, thresh_req):
    """
    Match the input feature vector and vector for each face in one image.
    Once a face matched, it will return True.
    If path and image coexist, then path will cover image.
    :param ref_id: just return it.
    :param thresh_req: the thresh for requirement.
    :param candidate_dict: dict, vectors to be matched.
    :param feature_vector: list, the feature vector to be matched
    :return:json:
        e.x. {"ref_id": ref_id, "result": 0, "message": "SUCCESS", "analysis_data":{"101":0.2}}
    """
    try:
        result = face.match_vectors(feature_vector, candidate_dict, thresh_req)
        result_json = json.dumps({"ref_id": ref_id, "result": 0, "message": "SUCCESS", "analysis_data": result})
    except Exception as e:
        msg = str(e)
        result_json = json.dumps({"result": -1, "message": msg})
    return result_json


def match_vectors_all(ref_id, feature_vector, candidate_dict):
    """
    Match the input feature vector and vector for each face in one image.
    Once a face matched, it will return True.
    If path and image coexist, then path will cover image.
    :param ref_id: just return it.
    :param candidate_dict: dict, vectors to be matched.
    :param feature_vector: list, the feature vector to be matched
    :return:json:
        e.x. {"ref_id": ref_id, "result": 0, "message": "SUCCESS", "analysis_data":{"101":0.2, "102":0.43}}
    """
    try:
        result = face.match_vectors_all(feature_vector, candidate_dict)
        result_json = json.dumps({"ref_id": ref_id, "result": 0, "message": "SUCCESS", "analysis_data": result})
    except Exception as e:
        msg = str(e)
        result_json = json.dumps({"result": -1, "message": msg})
    return result_json
